from abc import ABCMeta, abstractmethod

from ..container import ComponentContainer


class AbstractGradEvaluator(metaclass=ABCMeta):

    def __call__(self, container: ComponentContainer):
        optimizer = container.optimizer
        loss = container.loss
        self.evaluate(loss, optimizer)

    @abstractmethod
    def evaluate(self, loss, optimizer):
        pass


class SimpleGradEvaluator(AbstractGradEvaluator):

    def evaluate(self, loss, optimizer):
        loss.backward()
        optimizer.step()
